package com.csi.bumblebee.util;

import javax.swing.*;
import javax.swing.plaf.basic.BasicProgressBarUI;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SecureDeleteAppNew extends JWindow implements Runnable {

    private static final Logger logger = Logger.getLogger(SecureDeleteAppNew.class.getName());

    public static final int LOAD_WIDTH = 500; // 加载窗口宽度
    public static final int LOAD_HEIGHT = 150; // 加载窗口高度

    public JProgressBar progressBar;
    public JLabel statusLabel; // 用于显示状态信息
    public JLabel percentageLabel; // 用于显示百分比数字

    private int totalFiles = 0; // 总文件数
    private AtomicInteger deletedFiles = new AtomicInteger(0); // 使用 AtomicInteger 来保证线程安全

    private AtomicInteger deletedFilesError = new AtomicInteger(0); // 使用 AtomicInteger 来保证线程安全

    private static final int UPDATE_INTERVAL = 100;  // 每删除100个文件更新一次进度条

    private int executorsNumber = 1; //线程池大小

    private boolean rename = false; // 是否重命名

    // 增强模式和普通模式切换
    private boolean enhancedDeletionMode = false;  // 默认是普通模式

    private JTextField pathTextField; // 输入路径的文本框

    private AtomicInteger runningTasks = new AtomicInteger(0);

    private static final int BUFFER_SIZE = 8 * 1024;

    private final String[] extensions = {".txt", ".bin", ".dat", ".temp", ".xyz", ".lst", ".conf", ".sha1", ".dll", ".ini", ".c", ".odl"};

    private final String chars = "gB9z2JhN1XSm7rQp5k3Yw4V8cLxUO0AfZTnH6qRiEJsDCoPvWmTbGlyI5aF";


    static {
        try {
            // 设置 UIManager 的 LookAndFeel 为 Nimbus
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }

            // 创建日志目录
            File logDir = new File("C:\\SecurityOverlay");
            if (!logDir.exists()) {
                logDir.mkdirs(); // 创建文件夹
            }

            String logName = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            // 创建文件日志处理器
            FileHandler fileHandler = new FileHandler("C:\\SecurityOverlay\\" + logName + "-deletion.log", true);
            fileHandler.setEncoding("UTF-8");
            fileHandler.setFormatter(new CustomLogFormatter()); // 使用自定义格式化器
            logger.addHandler(fileHandler);
            logger.setLevel(Level.ALL);
        } catch (Exception e) {
            logger.warning("无法创建日志文件: " + e.getMessage());
        }
    }

    /**
     * 初始化进度条框
     */
    public SecureDeleteAppNew() {
        // 创建进度条
        progressBar = new JProgressBar();
        progressBar.setIndeterminate(false);
        progressBar.setStringPainted(false); // 设置默认百分比文字是否显示
        progressBar.setBounds(50, 40, LOAD_WIDTH - 100, 40);
        progressBar.setBackground(Color.LIGHT_GRAY); // 设置底色为浅灰色
        progressBar.setForeground(new Color(75, 179, 41, 252)); // 设置已加载部分颜色为绿色

        // 创建状态提示标签
        statusLabel = new JLabel("总文件数: 0, 已删除文件数: 0");
        statusLabel.setBounds(50, 80, LOAD_WIDTH - 100, 40);
        statusLabel.setFont(statusLabel.getFont().deriveFont(14f));
        statusLabel.setForeground(Color.BLACK); // 设置字体颜色为黑色

        // 创建百分比标签
        percentageLabel = new JLabel("0%");
        percentageLabel.setForeground(Color.BLACK); // 设置字体颜色为黑色

        // 设置窗口属性
        this.setLayout(null);
        this.setSize(LOAD_WIDTH, LOAD_HEIGHT);
        this.setLocationRelativeTo(null);
        this.add(progressBar);
        this.add(statusLabel);
        this.add(percentageLabel);
        this.setVisible(false);

        // 添加窗口关闭监听器
        this.addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
                System.exit(0); // 关闭窗口时退出程序
            }
        });

        // 自定义进度条
        progressBar.setUI(new ProgressBarUI());
    }

    /**
     * 初始化弹窗
     */
    private void showInputDialog() {
        // 创建一个垂直的 BoxLayout 布局
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));  // 垂直排列组件

        // 输入路径的文本框
        pathTextField = new JTextField(30);
        // 设置文本框高度为 30
        pathTextField.setPreferredSize(new Dimension(pathTextField.getPreferredSize().width, 30));
        pathTextField.setFont(new Font("Microsoft YaHei", Font.TRUETYPE_FONT, 14));

        // 选择文件夹按钮
        JButton selectButton = new JButton("选择文件夹");
        // 设置按钮高度为 30，宽度保持文本框的宽度
        selectButton.setPreferredSize(new Dimension(100, 30));

        // 选择文件夹按钮的点击事件
        selectButton.addActionListener(e -> {
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setDialogTitle("选择文件夹或文件");
            fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            fileChooser.setMultiSelectionEnabled(true); // 允许多选
            // 使用Nimbus样式的文件选择器
            UIManager.put("FileChooser.ui", "javax.swing.plaf.basic.BasicFileChooserUI");
            if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                File[] selectedFiles = fileChooser.getSelectedFiles(); // 获取选中的文件或文件夹
                StringBuilder filePaths = new StringBuilder();
                for (File file : selectedFiles) {
                    filePaths.append(file.getAbsolutePath()).append(";");
                }
                pathTextField.setText(filePaths.toString()); // 将选中的文件路径显示在文本框中
            }
        });

        // 创建一个面板来水平排列路径文本框和选择按钮
        JPanel pathPanel = new JPanel();
        pathPanel.setLayout(new FlowLayout(FlowLayout.LEFT));  // 水平排列组件
        pathPanel.add(selectButton);
        pathPanel.add(pathTextField);

        // 下拉框：是否重命名
        String[] renameOptions = {"否", "是"};
        JComboBox<String> renameComboBox = new JComboBox<>(renameOptions);
        renameComboBox.setSelectedIndex(0);  // 默认选择 "否"

        // 下拉框：选择删除模式
        String[] modeOptions = {"普通模式", "增强模式"};
        JComboBox<String> modeComboBox = new JComboBox<>(modeOptions);
        modeComboBox.setSelectedIndex(0);  // 默认选择 "普通模式"

        // 创建一个面板来包含"是否重命名"标签和下拉框
        JPanel renamePanel = new JPanel();
        renamePanel.setLayout(new FlowLayout(FlowLayout.LEFT));  // 水平排列组件
        renamePanel.add(new JLabel("是否重命名覆盖: "));
        renamePanel.add(renameComboBox);

        // 创建一个面板来包含"删除模式"标签和下拉框
        JPanel modePanel = new JPanel();
        modePanel.setLayout(new FlowLayout(FlowLayout.LEFT));  // 水平排列组件
        modePanel.add(new JLabel("删除模式: "));
        modePanel.add(modeComboBox);

        // 将路径面板和重命名面板添加到主面板
        panel.add(pathPanel);
        panel.add(Box.createVerticalStrut(5));  // 在两行之间添加一些垂直间距
        panel.add(renamePanel);
        panel.add(Box.createVerticalStrut(5));
        panel.add(modePanel);

        // 弹出对话框
        int result = JOptionPane.showConfirmDialog(null, panel, "输入路径",
                JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);

        // 确定按钮的操作
        if (result == JOptionPane.OK_OPTION) {
            String directoryPaths = pathTextField.getText().trim();
            String[] paths = directoryPaths.split(";");
            startDeletion(paths);
            rename = renameComboBox.getSelectedIndex() == 1;  // 判断是否选择了“是”
            enhancedDeletionMode = "增强模式".equals(modeComboBox.getSelectedItem());
        }
    }

    /**
     * 删除操作
     */
    private void startDeletion(String[] paths) {
        totalFiles = 0;
        deletedFiles.set(0); // 重置已删除文件数
        runningTasks.set(0);  // 重置运行中的任务数

        for (String path : paths) {
            File directory = new File(path);
            if (directory.exists() && (directory.isDirectory() || directory.isFile())) {
                countFiles(directory);
                progressBar.setMaximum(totalFiles); // 设置进度条最大值
                this.setVisible(true); // 显示窗口

                // 获取开始时间
                Instant start = Instant.now();

                // 使用 SwingWorker 执行删除操作
                SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
                    @Override
                    protected Void doInBackground() {
                        secureDelete(directory, true); // 第一次调用时标记为根目录
                        return null;
                    }

                    @Override
                    protected void done() {
                        int remainingTasks = runningTasks.decrementAndGet(); // 任务完成，减少计数

                        if (remainingTasks == 0) {  // 如果所有任务都完成
                            // 获取结束时间
                            Instant end = Instant.now();
                            Duration duration = Duration.between(start, end);
                            String format = String.format("%02d分%02d秒", duration.toMinutes(), duration.getSeconds() % 60);
                            logger.info("本次安全删除用时: " + format + ", 总文件: " + totalFiles + ", 已删除文件: " + deletedFiles.get() + ", 删除失败: " + deletedFilesError.get());
                            JOptionPane.showMessageDialog(SecureDeleteAppNew.this, "本次安全删除用时: " + format, "完成", JOptionPane.INFORMATION_MESSAGE);
                            SecureDeleteAppNew.this.dispose(); // 关闭加载窗口
                        }
                    }
                };

                // 增加任务计数
                runningTasks.incrementAndGet();
                worker.execute();
            } else {
                JOptionPane.showMessageDialog(this, "路径不存在，请检查路径!", "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }


    /**
     * 开始删除
     */
    private void secureDelete(File file, boolean isRoot) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                if (enhancedDeletionMode){
                    //获取CPU核心数
                    int cores = Runtime.getRuntime().availableProcessors();
                    if (cores !=0) {
                        executorsNumber = cores;
                    }
                }
                ExecutorService executor = Executors.newFixedThreadPool(executorsNumber); // 创建一个固定大小的线程池
                for (File subFile : files) {
                    executor.submit(() -> secureDelete(subFile, false)); // 并行删除文件
                }
                executor.shutdown();
                try {
                    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); // 等待所有任务完成
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (!isRoot && file.delete()) {
                logger.info("已删除目录: " + file.getAbsolutePath());
            }
        } else {
            try {
                boolean renamed = true;
                File renamedFile = file;
                if (rename){
                    String newFileName = generateRandomFileName("") + generateRandomExtension();
                    File files = new File(file.getParent(), newFileName);
                    renamed = file.renameTo(files);
                    renamedFile = files;
                }

                if (renamed) {

                    try (RandomAccessFile raf = new RandomAccessFile(renamedFile, "rw")) {
                        long fileSize = renamedFile.length();
                        SecureRandom random = new SecureRandom();

                        byte[] buffer = new byte[BUFFER_SIZE];
                        long totalBytesWritten = 0;

                        // 多次覆盖
                        for (int pass = 0; pass < 3; pass++) { // 可以调整为更多次
                            while (totalBytesWritten < fileSize) {
                                int bytesToWrite = (int) Math.min(BUFFER_SIZE, fileSize - totalBytesWritten);
                                random.nextBytes(buffer);

                                raf.seek(totalBytesWritten); // 确保文件指针在正确位置
                                raf.write(buffer, 0, bytesToWrite);
                                totalBytesWritten += bytesToWrite;
                            }
                            totalBytesWritten = 0; // 重置指针以便下一次覆盖
                        }

                        raf.getChannel().force(true); // 强制将所有更改写入磁盘

                    } catch (IOException e) {
                        logger.warning("文件删除错误: " + e.getMessage() + ", 文件路径: " + file.getAbsolutePath());
                    }

                    // 删除文件
                    if (renamedFile.delete()) {
                        deletedFiles.incrementAndGet(); // 增加已删除文件数
                        logger.info("已删除文件: " + renamedFile.getAbsolutePath());
                    }
                }
            } catch (Exception e) {
                deletedFilesError.incrementAndGet();
                e.printStackTrace();
                logger.warning("文件删除错误: " + e.getMessage() + ", 文件路径: " + file.getAbsolutePath());
            }
        }

        // 更新进度条和状态标签
        SwingUtilities.invokeLater(() -> {
            progressBar.setValue(deletedFiles.get());
            statusLabel.setText("总文件: " + totalFiles + ", 已删除文件: " + deletedFiles.get()+ ", 删除失败: " + deletedFilesError.get());
            int percentage = (int) ((deletedFiles.get() / (float) totalFiles) * 100);
            percentageLabel.setText(percentage + "%");
        });
    }

    private void countFiles(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File subFile : files) {
                    countFiles(subFile);
                }
            }
        } else {
            totalFiles++; // 增加总文件数
        }
    }

    private String generateRandomFileName(String str) {
        StringBuilder randomName = new StringBuilder();
        Random random = new Random();
        Random randomS = new Random();
        int randomNumber = randomS.nextInt(10 - 4) + 5;
        for (int i = 0; i < randomNumber; i++) {
            randomName.append(chars.charAt(random.nextInt(chars.length())));
        }
        return str + randomName.toString();
    }

    private String generateRandomExtension() {
        Random random = new Random();
        return extensions[random.nextInt(extensions.length)];
    }

    @Override
    public void run() {
        showInputDialog(); // 显示输入对话框
    }

    // 自定义进度条UI
    private static class ProgressBarUI extends BasicProgressBarUI {
        @Override
        protected Color getSelectionBackground() {
            return new Color(0, 123, 255); // 进度条的前景颜色
        }

        @Override
        protected Color getSelectionForeground() {
            return Color.WHITE;
        }

        @Override
        public Dimension getPreferredSize(JComponent c) {
            return new Dimension(LOAD_WIDTH - 100, 40); // 设置进度条的大小
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SecureDeleteAppNew app = new SecureDeleteAppNew();
            app.run();
        });
    }
}
